package org.linlinjava.litemall.wx.web;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.qcode.QCodeService;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallBookList;
import org.linlinjava.litemall.db.domain.LitemallCategory;
import org.linlinjava.litemall.db.domain.LitemallGoods;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.vo.SearchHistoryVo;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.HomeCacheManager;
import org.linlinjava.litemall.wx.util.IDHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 首页服务
 */
@RestController
@RequestMapping("/wx/home")
@Validated
public class WxHomeController {
    private final Log logger = LogFactory.getLog(WxHomeController.class);

    @Autowired
    private LitemallAdService adService;

    @Autowired
    private LitemallGoodsService goodsService;

    @Autowired
    private LitemallCategoryService categoryService;

    @Autowired
    private LitemallBookListService bookListService;

    @Autowired
    private QCodeService qCodeService;

    @Autowired
    private LitemallSearchHistoryService litemallSearchHistoryService;

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(9, 9, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);

    @GetMapping("/cache")
    public Object cache(@NotNull String key) {
        if (!key.equals("litemall_cache")) {
            return ResponseUtil.fail();
        }

        // 清除缓存
        HomeCacheManager.clearAll();
        return ResponseUtil.ok("缓存已清除");
    }

    /**
     * 首页数据
     *
     * @param userId    当用户已经登录时，非空。为登录状态为null
     * @param activeTab 0:租借页，1：商城页
     * @return 首页数据
     */
    @GetMapping("/index")
    public Object index(@LoginUser Integer userId, Integer activeTab) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Map<String, Object> entity = new HashMap<>();
        Callable<List> bannerListCallable;
        Callable<List> bookListCallable;
        FutureTask<List> bannerTask;
        FutureTask<List> bookListTask;

        if (activeTab.equals(0)) {
            //优先从缓存中读取
            if (HomeCacheManager.hasData(HomeCacheManager.INDEX_0)) {
                return ResponseUtil.ok(HomeCacheManager.getCacheData(HomeCacheManager.INDEX_0));
            }
            bannerListCallable = () -> adService.queryIndex((byte) 1);
            bookListCallable = () -> bookListService.queryList(1, 1, 4);

            bannerTask = new FutureTask<>(bannerListCallable);
            bookListTask = new FutureTask<>(bookListCallable);

            executorService.submit(bannerTask);
            executorService.submit(bookListTask);

            /*查询搜索记录*/
            List<SearchHistoryVo> historyList = new ArrayList<>();
            if (userId != null) {
                historyList = litemallSearchHistoryService.queryByUidWithOrder(userId, 10);
            }
            List<String> historyNameList = historyList.stream().map(SearchHistoryVo::getKeyword).collect(Collectors.toList());
            List<LitemallGoods> goodsList = new ArrayList<>();
//            if (historyList.size() > 0) {
//                historyNameList.forEach(historyName -> {
//                    LitemallGoods goods = goodsService.queryGuessYouLike(historyName);
//                    if (goods != null && goodsList.size() < 4) {
//                        goodsList.add(goods);
//                    }
//                });
//                if (goodsList.size() < 4) {
//                    goodsList.addAll(goodsService.queryCanBorrowedBooks(1, (4 - goodsList.size()), "add_time", "desc"));
//                }
//            } else {
            goodsList.addAll(goodsService.queryCanBorrowedBooks(0, 4, "add_time", "desc"));
//            }

            try {
                entity.put("banner", bannerTask.get());
                entity.put("borrowedBookList", bookListTask.get());
                entity.put("likeBooks", goodsList);
                HomeCacheManager.loadData(HomeCacheManager.INDEX_0, entity);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                executorService.shutdown();
            }
        } else {
            //优先从缓存中读取
            if (HomeCacheManager.hasData(HomeCacheManager.INDEX_1)) {
                return ResponseUtil.ok(HomeCacheManager.getCacheData(HomeCacheManager.INDEX_1));
            }
            bannerListCallable = () -> adService.queryIndex((byte) 2);
            Callable<List> allGoodsListCallable = () -> goodsService.queryAllGoods(1, 10);
            bookListCallable = () -> bookListService.queryList(2, 1, 4);

            bannerTask = new FutureTask<>(bannerListCallable);
            FutureTask<List> allGoodsListTask = new FutureTask<>(allGoodsListCallable);
            bookListTask = new FutureTask<>(bookListCallable);

            executorService.submit(bannerTask);
            executorService.submit(allGoodsListTask);
            executorService.submit(bookListTask);

            try {
                entity.put("banner", bannerTask.get());
                entity.put("recommendBooks", allGoodsListTask.get());
                entity.put("sellBookList", bookListTask.get());
                HomeCacheManager.loadData(HomeCacheManager.INDEX_1, entity);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                executorService.shutdown();
            }
        }
        return ResponseUtil.ok(entity);
    }

    private List<Map> getCategoryList() {
        List<Map> categoryList = new ArrayList<>();
        List<LitemallCategory> catL1List = categoryService.queryL1WithoutRecommend(1, SystemConfig.getCatlogListLimit());
        for (LitemallCategory catL1 : catL1List) {
            List<LitemallCategory> catL2List = categoryService.queryByPid(catL1.getId());
            List<Integer> l2List = new ArrayList<>();
            l2List.add(catL1.getId());
            for (LitemallCategory catL2 : catL2List) {
                l2List.add(catL2.getId());
            }

            List<LitemallGoods> categoryGoods;
            if (l2List.size() == 0) {
                categoryGoods = new ArrayList<>();
            } else {
                categoryGoods = goodsService.queryByCategory(l2List, 1, SystemConfig.getCatlogMoreLimit());
            }

            Map<String, Object> catGoods = new HashMap<>();
            catGoods.put("id", catL1.getId());
            catGoods.put("name", catL1.getName());
            catGoods.put("goodsList", categoryGoods);
            categoryList.add(catGoods);
        }
        return categoryList;
    }

    /**
     * 商城介绍信息
     *
     * @return 商城介绍信息
     */
    @GetMapping("/about")
    public Object about() {
        LitemallBookList aboutus = bookListService.findById(1);
        return ResponseUtil.ok(aboutus);
    }

    /**
     * 商城配置信息
     *
     * @return 商城配置信息
     */
    @GetMapping("/setting")
    public Object setting() {
        Map<String, Object> re = new HashMap<>();
        re.put("spellTime", SystemConfig.getSpellUnpaid() / 60);
        re.put("shareName", SystemConfig.getWxShareName());
        re.put("shareDesc", SystemConfig.getWxShareDesc());
        re.put("customPhone", SystemConfig.getWxPhone());
        re.put("shareImage", SystemConfig.getWxShareUrl());
        return ResponseUtil.ok(re);
    }

    /**
     * 获取带个人信息的分享图片
     *
     * @param userId
     * @return
     */
    @GetMapping("share_url")
    public Object shareUrl(@LoginUser Integer userId) {
        String url = qCodeService.createIndexShareImage(IDHelper.encrypt(userId));
        return ResponseUtil.ok(url);
    }
}